home *** CD-ROM | disk | FTP | other *** search
- ;;;;
- ;;;; {\bf Utilities}
- ;;;;
- (define make-tk-name
- (lambda (parent)
- (gensym (format #f "~A.v" (if (eq? parent *root*) "" (Id parent))))))
-
- (define split-options
- (lambda (valid-slots initargs)
- (letrec
- ((separate
- (lambda (valids args tk-opt other)
- (if (null? args)
- (cons tk-opt other)
- (if (member (car args) valids)
- (separate valids (cddr args)
- (list* (car args) (cadr args) tk-opt)
- other)
- (separate valids (cddr args)
- tk-opt
- (list* (car args) (cadr args) other)))))))
- (separate valid-slots initargs '() '()))))
-
- ;;;;
- ;;;; {\bf Simple widgets}
- ;;;;
- ;;
- ;; <Tk-metaclass> class definition and associated methods
- ;;
- (define-class <Tk-Metaclass> (<class>)
- ((valid-options :accessor Tk-valid-options)))
-
-
- (define-method initialize ((class <Tk-Metaclass>) initargs)
- (next-method)
- ;; Build a list of allowed keywords. These keywords will be passed to
- ;; the Tk-command at build time
- (let ((slots (slot-ref class 'slots))
- (res '())
- (tk-virtual? (lambda(s)
- (eqv? (get-slot-allocation s) :tk-virtual))))
- (for-each (lambda (s)
- (when (tk-virtual? s)
- (let ((key (make-keyword (car s))))
- (set! res (cons key res)))))
- slots)
- ;; Store this list in the new allocated class
- (set! (Tk-valid-options class) res)))
-
-
- (define-method compute-get-n-set ((class <Tk-Metaclass>) slot)
- (if (eqv? (get-slot-allocation slot) :tk-virtual)
- ;; this is a Tk-virtual slot
- (let ((opt (make-keyword (car slot))))
- (list (lambda (o) (list-ref ((Id o) 'configure opt) 4))
- (lambda (o v) ((Id o) 'configure opt v))))
- ;; call super compute-get-n-set
- (next-method)))
-
- ;;
- ;; Basic virtual classes for widgets: <Tk-object>, <Tk-widget> and
- ;; <Tk-simple-widget>
- ;;
- (define-class <Tk-object> ()
- ((Id :accessor Id) ;; Widget Id
- (parent :accessor parent :init-keyword :parent))) ;; Parent widget
-
- (define-class <Tk-widget> (<Tk-object>)
- ())
-
-
-
- (define-class <Tk-simple-widget> (<Tk-widget>)
- ;; Each widget has at least the slot bg for its background colour
- ((bg :accessor bg :init-keyword :bg :allocation :tk-virtual))
- :metaclass <Tk-Metaclass>)
-
-
- (define-method initialize ((self <Tk-simple-widget>) initargs)
- ;; Use split-options on initargs to separate STklos slots
- ;; from Tk ones. Set parent to the root window if not specified
- ;; in initargs
- (let* ((options (split-options (Tk-valid-options (class-of self))
- initargs))
- (parent (get-keyword :parent (cdr options) *root*)))
- ;; Call the Tk command which creates the widget
- (set! (Id self) (apply (tk-constructor self)
- (make-tk-name parent)
- (car options)))
- ;; Initialize other slots (i.e. non Tk-virtual ones)
- (next-method self (cdr options))))
-
-
- ;;
- ;; We can now define three widget classes: <Label>, <Button> and <Canvas>
- ;; as well as their associated Tk-command
- ;;
- (define-class <Label> (<Tk-simple-widget>)
- ((font :accessor font :init-keyword :font :allocation :tk-virtual)
- (text :accessor text :init-keyword :text :allocation :tk-virtual)))
-
- (define-class <Button> (<Label>)
- ((command :accessor command :init-keyword :command
- :allocation :tk-virtual)))
-
- (define-class <Canvas> (<Tk-simple-widget>)
- ())
-
- (define-method tk-constructor ((self <Label>)) label)
- (define-method tk-constructor ((self <Button>)) button)
- (define-method tk-constructor ((self <Canvas>)) canvas)
-
-
- ;;;;
- ;;;; {\bf Canvas items widgets}
- ;;;;
- ;;
- ;; <Tk-item-metaclass> class definition and associated methods
- ;;
-
- (define-class <Tk-item-metaclass> (<Tk-Metaclass>)
- ())
-
- (define-method compute-get-n-set ((class <Tk-item-metaclass>) slot)
- (if (eqv? (get-slot-allocation slot) :tk-virtual)
- ;; this is a Tk-virtual slot
- (let ((opt (make-keyword (car slot))))
- (list (lambda (obj)
- (list-ref ((Id obj) 'itemconfigure (Cid obj) opt) 4))
- (lambda (obj val)
- ((Id obj) 'itemconfigure (Cid obj) opt val))))
- ;; call super compute-get-n-set
- (next-method)))
-
- ;;
- ;; Basic virtual class: <Tk-canvas-item>
- ;;
- (define-class <Tk-canvas-item> (<Tk-object>)
- ((Cid :accessor Cid)
- (width :accessor width :allocation :tk-virtual))
- :metaclass <Tk-item-metaclass>)
-
-
- (define-method initialize ((self <Tk-canvas-item>) initargs)
- (let* ((options (split-options (Tk-valid-options (class-of self))
- initargs))
- (parent (get-keyword :parent (cdr options) #f))
- (coords (get-keyword :coords (cdr options) #f)))
- (if (not (and parent coords))
- (error "Parent widget and coordinates must be given!!"))
- (set! (Id self) (Id parent))
- (set! (CId self) (apply (Id parent)
- 'create
- (canvas-item-initializer self)
- (append coords (car options))))
- ;; Initialize other slots (i.e. non Tk-virtual ones)
- (next-method self (cdr options))))
-
- ;;
- ;; We can now define two canvas item classes: <Line> and <Rectangle>
- ;; as well as their associated initializer
- ;;
- (define-class <Line> (<Tk-canvas-item>)
- ())
-
- (define-class <Rectangle> (<Tk-canvas-item>)
- ((fill :accessor fill :init-keyword :fill :allocation :tk-virtual)))
-
- (define-method canvas-item-initializer ((self <Rectangle>)) "rectangle")
- (define-method canvas-item-initializer ((self <Line>)) "line")
-